package dryven.init;

import java.util.Collection;
import java.util.LinkedList;

import dryven.model.di.LocalThreadStorage;
import dryven.model.di.DependencyInjector;
import dryven.model.di.DependencyInjectorBinder;
import dryven.model.di.DefaultDependencyService;
import dryven.model.di.DependencyService;
import dryven.request.FrontController;
import dryven.request.RequestLifeCycleListener;
import dryven.request.controller.ControllerDescription;
import dryven.request.controller.ControllerFactory;
import dryven.request.controller.DependencyInjectingControllerFactory;
import dryven.request.controller.paramtransform.ActionParameterBindCandidate;
import dryven.request.controller.paramtransform.ActionParameterFillCandidate;
import dryven.request.controller.paramtransform.ActionParameterTransformCandidate;
import dryven.request.controller.result.ActionResult;
import dryven.request.routing.Router;

public abstract class DependencyInjectingFrontControllerFactory extends
		AbstractFrontControllerFactory {

	private Collection<DependencyInjector> _dependencyInjectors;
	private DefaultDependencyService _dependencyService;

	@Override
	protected FrontController create() {
		getDependencyService();
		return super.create();
	}
	
	@Override
	protected void addActionParameterBinders(
			Collection<ActionParameterBindCandidate> binders) {
		for (DependencyInjector di : getDependencyInjectors()) {
			binders.add(new DependencyInjectorBinder(di));
		}
	}
	
	@Override
	protected ControllerFactory createControllerFactory() {
		return new DependencyInjectingControllerFactory(getDependencyService());
	}

	protected Iterable<DependencyInjector> getDependencyInjectors() {
		if(_dependencyInjectors==null) {
			_dependencyInjectors = new LinkedList<DependencyInjector>();
			addDependencyInjectors(_dependencyInjectors);
		}
		return _dependencyInjectors;
	}
	protected abstract void addDependencyInjectors(Collection<DependencyInjector> dis);

	@Override
	protected DependencyService getDependencyService() {
		if(_dependencyService==null) {
			_dependencyService = new DefaultDependencyService();
			_dependencyService.setInjectors(getDependencyInjectors());
		}
		return _dependencyService;
	}
}
